package dapps.web.proj;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.ProjectionList;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Property;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springside.modules.orm.Page;
import org.springside.modules.web.struts2.CRUDActionSupport;
import org.springside.modules.web.struts2.Struts2Utils;

import dapps.entity.proj.Proj;
import dapps.entity.proj.Type;
import dapps.entity.user.User;
import dapps.service.ServiceException;
import dapps.service.proj.PlanManager;
import dapps.service.proj.ProjManager;

@SuppressWarnings("serial")
@Results( { 
	@Result(name = CRUDActionSupport.RELOAD, location = "proj.action?page.pageRequest=${page.pageRequest}&iprorank=${iprorank}&iyeartime=${iyeartime}", type = "redirect") 
	})
public class ProjAction extends CRUDActionSupport<Proj> {

	@Autowired
	private ProjManager projManager;

	@Autowired
	private PlanManager planManager;
	// 基本属性
	private Proj entity;
	private Long id;
	private Long typeid;
	private Integer tid;
	private Long dutycompid;
	private Long applicateuserid;
	private Integer iyeartime;
	private Integer iprorank;
	private Boolean checkboxplan = true;
	private Boolean checkboxprogress = false;
	private Boolean checkboxsame = false;
	private Page<Proj> page = new Page<Proj>(14);//每页5条记录
	HttpServletRequest request = Struts2Utils.getRequest();
	Map<String,Object> staticsMap ;
	List<Map<String,Object>> dutycount;
	private ServletContext application = Struts2Utils.getApplication();
	private Integer[] ps  = (Integer[])application.getAttribute("planarray");
	// 角色相关属性

	private List<Object> yeartimelist;
	// 基本属性访问函数 //

	
	public Proj getModel() {
		return entity;
	}

	
	@Override
	protected void prepareModel() throws Exception {

		if (id != null) {
			entity = projManager.get(id);
			if(entity.getType()!=null) typeid = entity.getType().getId();
			if(entity.getDutycomp()!=null) dutycompid = entity.getDutycomp().getId();
		} else {
			entity = new Proj();			
		}
		
	}

	@Override
	public String list() throws Exception {
		
		List<Criterion> criterionlist = new ArrayList<Criterion>();
		HttpServletRequest request = Struts2Utils.getRequest();
		String title = request.getParameter("filter_LIKE_title");
		String content = request.getParameter("filter_LIKE_content");
		
		if(StringUtils.isNotBlank(title)) criterionlist.add(Restrictions.like("title", title, MatchMode.ANYWHERE));
		if(StringUtils.isNotBlank(content)) criterionlist.add(Restrictions.like("content", content, MatchMode.ANYWHERE));
		
		if(yeartimelist==null||yeartimelist.isEmpty()){
			Criterion[] cs ={Restrictions.ge("yeartime", 0)};
			Order[] os ={Order.desc("yeartime")};
			yeartimelist=planManager.getDistinctlist("yeartime", cs, os);
		}
		if(iprorank!=null&&iprorank>=0){	
			criterionlist.add(Restrictions.eq("prorank",iprorank));
		}else{
			criterionlist.add(Restrictions.ne("prorank",9));
		}
		if (iprorank==null||iprorank != 0) {// 预备储备 查询
			Integer minyear = (Integer) yeartimelist.get(yeartimelist.size() - 1);
			Integer maxyear = (Integer) yeartimelist.get(0);
			yeartimelist.clear();
			for (int i = maxyear / 100; i >= minyear / 100; i--) {
				yeartimelist.add(i);
			}
			if (iyeartime == null) {
				if (ps[0] != 0) iyeartime = ps[0] / 100;
				else if (ps[1] != 0) iyeartime = ps[1] / 100;
				else if (ps[2] != 0) iyeartime = ps[2] / 100;
				else  iyeartime = maxyear / 100;
			}
			criterionlist.add(Property.forName("yeartime").between(iyeartime * 100,(iyeartime + 1) * 100));
			if(iprorank<0&&!checkboxplan){//不包含计划实施
				criterionlist.add(
						Restrictions.or(
								Restrictions.and(Restrictions.eq( "prorank", 0 )
												,Restrictions.gt( "yeartime", planManager.getMaxPlaned(iyeartime*100))),
								Restrictions.gt("prorank", 0 )
						)
				 );
			}
			
		} else {// 实施
			if (iyeartime == null) {
				if (ps[0] != 0) iyeartime = ps[0];
				else if (ps[1] != 0) iyeartime = ps[1];
				else if (ps[2] != 0) iyeartime = ps[2];
				else iyeartime = (Integer) yeartimelist.get(0);
			}
			criterionlist.add(Restrictions.eq("yeartime",iyeartime));
		}
		if(tid!=null&&tid>=0){			
			if(tid%100!=0) criterionlist.add(Restrictions.eq("t.tid",tid));				
			else{
				criterionlist.add(Property.forName("t.tid").between(tid,tid+99));
			}
		}
		if(dutycompid!=null&&dutycompid>=0){		
			criterionlist.add(Restrictions.eq("dutycomp.id",dutycompid));
		}
		if(applicateuserid!=null&&applicateuserid>=0){		
			criterionlist.add(Restrictions.eq("applicateuser.id",applicateuserid));
		}

		
		String[] alias={"type","t","dutycomp","d"};
		if(StringUtils.isBlank(page.getOrderBy())){
			page.setOrderBy("t.tid,d.uorder,id");page.setOrder("asc,asc,asc");
		}
		Criterion[] ca = criterionlist.toArray(new Criterion[criterionlist.size()]);
		if(checkboxsame) {
			Order[] orders={Order.asc("agrarea")};
			List<Proj> pl = projManager.FullSearch(null, ca, alias, orders);
			List<Proj> dupl = new ArrayList<Proj>();
			int k=0;int i=0;
			//for(int i=0;i<pl.size();i++){
			while(i<pl.size()-1){
				Proj p = pl.get(i);k=0;				
				for(int j=i+1;j<pl.size();j++){
					Proj pp = pl.get(j);
					if(p.getAgrarea()!=null&&p.getAgrarea()!=null&&p.getAgrarea().equals(pp.getAgrarea())){
						if(this.longestSubstr(p.getTitle(), pp.getTitle())>3){
							if(k==0) {pl.remove(p);j--;dupl.add(p);k++;}
							pl.remove(pp);j--;dupl.add(pp);														
						}
					}else{
						if(k==0) i++;//非重复残留
						break;
					}
				}
			}
			page.setResult(dupl);page.setPageSize(dupl.size());page.setTotalCount(dupl.size());
		}else{
			page = projManager.findByCriteria(page,null, ca, alias);
		}
		
		
		//统计
		String[] pn = {"sum_invest","sum_area","sum_agrarea","sum_farmingarea"};
		staticsMap = projManager.staticsByCriteria(pn, ca,alias);
		
		//已申报单位
		ProjectionList pl= Projections.projectionList();
		pl.add(Projections.count("id"), "count");		
		pl.add(Projections.groupProperty("d.name"),"dutycompnm");
		Order[] orders={Order.asc("d.uorder")};
		dutycount = projManager.groupByCriteria(pl,criterionlist,alias,orders);

		return SUCCESS;
	}
	

	
	@Override
	public String input() throws Exception {
		//allTypesOrder = typeManager.getAll();			
		return INPUT;
	}

	@Override
	public String save() throws Exception {

		if(typeid!=null){
			Type type = new Type();
			type.setId(typeid);
			entity.setType(type);
		}
		if(dutycompid!=null){
			User dc = new User();
			dc.setId(dutycompid);
			entity.setDutycomp(dc);
		}
		if(entity.getSl()==0&&entity.getForced()==2) entity.setForced(0);//forced==2 means sl==1
		if(entity.getSl()==1){
			entity.setProrank(3);
			entity.setForced(2);
		}
		if(entity.getForced()==0){
			if(projManager.isSs(entity)){
				if(entity.getProrank()>0){
					Integer maxplan = planManager.getMaxPlaned(entity.getYeartime());
					if(entity.getYeartime()<=maxplan ){
						entity.setYeartime(maxplan+1);
					}
				}
				entity.setProrank(0);//实施
			}			
			else if(projManager.isCb(entity)){
				entity.setProrank(2);//储备
			}			
			else{
				entity.setProrank(1);//预备
			}
		}
		
		projManager.saveProj(entity);
		addActionMessage("保存项目成功");
		return RELOAD;
	}
	


	
	@Override
	public String delete() throws Exception {
		try {
			projManager.delete(id);
			addActionMessage("删除项目成功");
		} catch (ServiceException e) {
			logger.error(e.getMessage(), e);
			addActionMessage(e.getMessage());
		}
		return RELOAD;
	}
	
	public int longestSubstr(String str_, String toCompare_) 
	{
	  if (str_.isEmpty() || toCompare_.isEmpty())
	    return 0;
	 
	  int[][] compareTable = new int[str_.length()][toCompare_.length()];
	  int maxLen = 0;
	 
	  for (int m = 0; m < str_.length(); m++) 
	  {
	    for (int n = 0; n < toCompare_.length(); n++) 
	    {
	      compareTable[m][n] = (str_.charAt(m) != toCompare_.charAt(n)) ? 0
	          : (((m == 0) || (n == 0)) ? 1
	              : compareTable[m - 1][n - 1] + 1);
	      maxLen = (compareTable[m][n] > maxLen) ? compareTable[m][n]
	          : maxLen;
	    }
	  }
	  return maxLen;
	}
	


	// 其他属性访问函数与Action函数 //


	public Long getTypeid() {
		return typeid;
	}

	public Long getDutycompid() {
		return dutycompid;
	}


	public Map<String, Object> getStaticsMap() {
		return staticsMap;
	}

	public List<Object> getYeartimelist() {
		return yeartimelist;
	}
	
	public Integer getIyeartime() {		
		return iyeartime;
	}
	public Integer getIprorank() {
		return iprorank;
	}

	public void setIprorank(Integer iprorank) {
		this.iprorank = iprorank;
	}

	public void setIyeartime(Integer iyeartime) {
		this.iyeartime = iyeartime;
	}
	public void setId(Long id) {
		this.id = id;
	}
	public void setTypeid(Long typeid) {
		this.typeid = typeid;
	}
	public Page<Proj> getPage() {
		return page;
	}
	public void setDutycompid(Long dutycompid) {
		this.dutycompid = dutycompid;
	}


	public Integer getTid() {
		return tid;
	}


	public Long getApplicateuserid() {
		return applicateuserid;
	}


	public void setApplicateuserid(Long applicateuserid) {
		this.applicateuserid = applicateuserid;
	}


	public void setTid(Integer tid) {
		this.tid = tid;
	}


	public Boolean getCheckboxplan() {
		return checkboxplan;
	}


	public void setCheckboxplan(Boolean checkboxplan) {
		this.checkboxplan = checkboxplan;
	}



	public List<Map<String, Object>> getDutycount() {
		return dutycount;
	}


	public void setDutycount(List<Map<String, Object>> dutycount) {
		this.dutycount = dutycount;
	}


	public Boolean getCheckboxprogress() {
		return checkboxprogress;
	}


	public void setCheckboxprogress(Boolean checkboxprogress) {
		this.checkboxprogress = checkboxprogress;
	}


	public Boolean getCheckboxsame() {
		return checkboxsame;
	}


	public void setCheckboxsame(Boolean checkboxsame) {
		this.checkboxsame = checkboxsame;
	}



}
